/* The file is saved in UTF-8 codepage.
 * Check: «Stereotype», Section mark-§, Copyright-©, Alpha-α, Beta-β, Smile-☺
 */
package cz.pecinovsky.english.lootp._134_;


import cz.pecinovsky.english.lootp.manager.Painter;


import cz.pecinovsky.english.lootp.manager.CanvasManager_Envelope.               CanvasManager;
import cz.pecinovsky.english.lootp._134_.Ring_134_.                             Ring;
import cz.pecinovsky.english.lootp._134_.IRotable_136_.                          IRotable;
import cz.pecinovsky.english.lootp._134_.Arrow_134_.                             Arrow;
import cz.pecinovsky.english.lootp._134_.IRace_138_.                             IRace;
import cz.pecinovsky.english.lootp._134_.IRacer_137_.                            IRacer;
import cz.pecinovsky.english.lootp._134_.Závod_137_.                             Závod;


import cz.pecinovsky.english.lootp._134_.Vozidlo_B_137_.Vozidlo_B;
////////////////////////////////////////////////////////////////////////////////
//%%+  +++++ End of ignored starting test - place for imports +++++
//%I+
//import cz.pecinovsky.english.lootp.canvasmanager.Painter;
//import cz.pecinovsky.english.lootp.canvasmanager.CanvasManager;
//%I-

import cz.pecinovsky.english.lootp.utility.NamedColor;
import cz.pecinovsky.english.lootp.utility.Position;
import cz.pecinovsky.english.lootp.utility.Direction8;
//%X+ xxxxx Start of the ovejumped text with declaration of the envelope xxxxx
/*******************************************************************************
 *<pre>
 * Předchozí:   Není - toto_je_nově_definovaná_třída
 *              Ttt v projektu Ppp
 * Následující: Prozatím není
 *
 * Projekt  Ppp
 *   + Přidáno
 *   - Odebráno
 *   ~ Změněno
 *</pre>
 */
public class Vozidlo_B_137_
{    private Vozidlo_B_137_() {}   static
////////////////////////////////////////////////////////////////////////////////
//%X- ----- End of the ovejumped text with declaration of the envelope -----


/*******************************************************************************
 * Instance třídy {@code Vozidlo_B} představují
 * "pojízdné", z klávesnice ovladatelné objekty,
 * které je možné přihlásit k závodům.
 *
 * @author Rudolf PECINOVSKÝ
 * @version 6.03.2017 — 2010-11-08
 */
public class Vozidlo_B implements IRacer
{
//== CONSTANT CLASS ATTRIBUTES =================================================

    /** Canvas, na které se bude instance kreslit. */
    private static final CanvasManager CM = CanvasManager.getInstance();



//== VARIABLE CLASS ATTRIBUTES =================================================

    /** Rychlost pohybu, tj. o kolik bodů se objekt posune po jednom příkazu. */
    private int speed = CM.getStep();



//== STATIC CONSTRUCTOR (CLASS INITIALIZER, STATIC INICITALIZING BLOCK) ========
//== CONSTANT INSTANCE ATTRIBUTES ==============================================

    /** Dekorovaný objekt, který bude ovládán z klávesnice. */
    private final IRotable decorated;



//== VARIABLE INSTANCE ATTRIBUTES ==============================================

    /** Závod, u nějž se závodník registroval. */
//%I+ <138
//    private Závod závod;
//%I-
//%A+ >138
    private IRace závod;
//%A-

    /** Pojmenování závodníka, které usnadní jeho identifikaci. */
    private String name;


//== CLASS GETTERS AND SETTERS =================================================
//== OTHER NON-PRIVATE CLASS METHODS ===========================================

//##############################################################################
//== CONSTUCTORS AND FACTORY METHODS ===========================================

    /***************************************************************************
     * Obalí otočný objekt zadaný v parametru schopností býti ovládán
     * z klávesnice.
     *
     * @param ovládaný Dekorovaný objekt
     */
    public Vozidlo_B(IRotable ovládaný)
    {
        this.decorated = ovládaný;
    }



//== ABSTRACT METHODS ==========================================================
//== INSTANCE GETTERS AND SETTERS ==============================================

    /***************************************************************************
     * Vrátí name instance - implicitně name třídy následovaný ID instance.
     *
     * @return  Řetězec s názvem instance.
     */
    @Override
     public String getName()
     {
        return name;
     }


    /***************************************************************************
     * Nastaví nový name instance.
     *
     * @param name  Řetězec s novým názvem instance.
     */
    @Override
    public void setName(String name)
    {
        this.name = name;
    }


    /***************************************************************************
     * Vrátí přepravku se souřadnicemi instance.
     *
     * @return  Přepravka se souřadnicemi instance
     */
    @Override
    public Position getPosition()
    {
        return decorated.getPosition();
    }


    /***************************************************************************
     * Nastaví novou pozici instance.
     *
     * @param pozice  Nová pozice instance
     */
    @Override
    public void setPosition(Position pozice)
    {
        decorated.setPosition(pozice);
    }


    /***************************************************************************
     * Nastaví novou pozici instance.
     *
     * @param x   Nová x-ová pozice instance
     * @param y   Nová y-ová pozice instance
     */
    @Override
    public void setPosition(int x, int y)
    {
        decorated.setPosition(x, y);
    }


    /***************************************************************************
     * Vrátí základní délku, od níž se odvozují všechny rozměry objektu.
     *
     * @return Velikost modulu
     */
    @Override
    public int getModule()
    {
        return decorated.getModule();
    }


    /***************************************************************************
     * Nastaví nový základní rozměr objektu,
     * od nějž se odvozují jeho ostatní rozměry.
     *
     * @param module Nově nastavovaný module
     */
    @Override
    public void setModule(int module)
    {
        //Upravíme speed, aby byl zachován její poměr vůči modulu
        speed = speed * module / decorated.getModule();
        if (speed == 0) {
            speed = 1;
        }
        decorated.setModule(module);
    }


    /***************************************************************************
     * Vrátí direction, do nějž je instance natočena.
     *
     * @return Směr, do nějž je instance natočena
     */
    @Override
    public Direction8 getDirection()
    {
        return decorated.getDirection();
    }


    /***************************************************************************
     * Natočí instanci do nového směru.
     *
     * @param direction Směr, do nějž chceme instanci natočit
     */
    @Override
    public void setDirection(Direction8 direction)
    {
        decorated.setDirection(direction);
    }



//%X+
    @Override public int getX() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    @Override public int getY() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
//%X-
//== OTHER NON-PRIVATE INSTANCE METHODS ========================================

    /***************************************************************************
     * Metoda oznámí závodníku registraci na závodě obdrženém v parametru.
     * Tomuto závodu pak bude hlásit jednotlivé dosažené pozice.
     *
     * @param závod Závod, u nějž je závodník registrován
     */
    @Override
//%I+ <138
//    public void registerFor(Závod závod)
//%I-
//%A+ >138
    public void registerFor(IRace závod)
//%A-
    {
        this.závod = závod;
        závod.registration(this);
    }


    /***************************************************************************
     * Reakce na stisk klávesy se šipkou vpravo.
     */
    @Override
    public void vpravo()
    {
        Direction8 direction = decorated.getDirection();
        decorated.setDirection(direction.rightFace());
    }


    /***************************************************************************
     * Reakce na stisk klávesy se šipkou vlevo.
     */
    @Override
    public void vlevo()
    {
        Direction8 direction = decorated.getDirection();
        decorated.setDirection(direction.leftFace());
    }


    /***************************************************************************
     * Reakce na stisk klávesy se šipkou vzhůru.
     */
    @Override
    public void vzhůru()
    {
        popojeď(speed);
    }


    /***************************************************************************
     * Reakce na stisk klávesy se šipkou dolů.
     */
    @Override
    public void dolů()
    {
        popojeď(-speed);
    }


    /***************************************************************************
     * Reakce na stisk klávesy enter.
     */
    @Override
    public void enter()
    {
    }


    /***************************************************************************
     * Reakce na stisk mezerníku.
     */
    @Override
    public void mezera()
    {
    }


    /***************************************************************************
     * Reakce na stisk klávesy ESC, tj. na ukončení ovládání z klávesnice.
     */
    @Override
    public void konec()
    {
    }


    /***************************************************************************
     * Prostřednictvím dodaného kreslítka vykreslí obraz své instance.
     *
     * @param painter Painter, které nakreslí instanci
     */
    @Override
    public void paint(Painter painter)
    {
        decorated.paint(painter);
    }


    /***************************************************************************
     * Vrátí řetězec sloužící jako textový "podpis" instance
     * používaný především při ladění.
     */
    @Override
    public String toString()
    {
        return "Vozidlo_B_(" + decorated.toString() + ")";
    }



//== PRIVATE AND AUXILIARY CLASS METHODS =======================================
//== PRIVATE AND AUXILIARY INSTANCE METHODS ====================================

    /***************************************************************************
     * Přesune vozidlo o zadanou vzdálenost směrem, kterým je natočeno;
     * je-li vzdálenost záporná, tak směrem opačným.
     * Přitom kontroluje, jestli vozidlo po přesunu neopustí plátno.
     * Pokud by je opustilo,nepřesune jej.
     *
     * @param vzdálenost Vzdálenost, o kterou se má vozidlo posunout
     */
    private void popojeď(int vzdálenost)
    {
        Position pozice = decorated.getPosition();
        Direction8 direction = decorated.getDirection();
        pozice = direction.nextPosition(pozice, vzdálenost);
        if ((pozice.x < 0)  ||  (pozice.x >= CM.getWidthInPixels())  ||
            (pozice.y < 0)  ||  (pozice.y >= CM.getHeightInPixels()))
        {
            return;         //==========>
        }
        decorated.setPosition(pozice);
        závod.checkpoint(this);
    }



//== EMBEDDED TYPES AND INNER CLASSES ==========================================
//== TESTING CLASSES AND METHODS ===============================================

    /***************************************************************************
     * Test method.
     */
    public static void test()
    {
        Arrow arrow  = new Arrow();
        Vozidlo_B vb = new Vozidlo_B(arrow);
        Závod  závod = new Závod(Ring.elko(new Position(0,0), NamedColor.BROWN));
//                                  Ring.čtverec(new Position(50,50)));
        vb.setName("První");
        vb.registerFor(závod);
    }

//    /** @param args Parametry příkazového řádku - nepoužívané. */
//    public static void main(String[] args)  {  test();  }
    }

//%%- ---- Start of the ovejumped text with closing of the envelope ----
////////////////////////////////////////////////////////////////////////////////
//== TESTING CLASSES AND METHODS ===============================================

    /***************************************************************************
     * Test method.
     */
    public static void test()
    {
        Vozidlo_B.test();
    }
    /** @param args Parametry příkazového řádku - nepoužívané. */
    public static void main(String[] args)  {  test();  }
}
